home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / tiff / mkg3states.c < prev    next >
C/C++ Source or Header  |  1995-06-21  |  27KB  |  889 lines

  1. /* "$Header: /usr/people/sam/tiff/libtiff/RCS/mkg3states.c,v 1.23 1994/09/29 17:13:36 sam Exp $ */
  2.  
  3. /*
  4.  * Copyright (c) 1991, 1992, 1993, 1994 Sam Leffler
  5.  * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26.  
  27. /*
  28.  * Program to construct Group 3 & Group 4 decoding tables.
  29.  *
  30.  * This code is derived from code by Michael P. Marking.  In
  31.  * particular, the algorithms to generate the null_mode and
  32.  * horiz_mode state tables are his.  See the comments below
  33.  * for more information.
  34.  *
  35.  * BEGIN (from the original source)
  36.  LEGAL
  37.  *    Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039,
  38.  *    Scottsdale, Arizona 85252-8039. All rights reserved.
  39.  *
  40.  *    License is granted by the copyright holder to distribute and use this
  41.  *    code without payment of royalties or the necessity of notification as
  42.  *    long as this notice (all the text under "LEGAL") is included.
  43.  *
  44.  *    Reference: $Id: mkg3states.c,v 1.23 1994/09/29 17:13:36 sam Exp $
  45.  *
  46.  *    This program is offered without any warranty of any kind. It includes
  47.  *    no warranty of merchantability or fitness for any purpose. Testing and
  48.  *    suitability for any use are the sole responsibility of the user.
  49.  *
  50.  INFORMATION
  51.  *    Although there is no support offered with this program, the author will
  52.  *    endeavor to correct errors. Updates will also be made available from
  53.  *    time to time.
  54.  *
  55.  *    Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona
  56.  *    85252-8039 USA. Replies are not guaranteed to be swift. Beginning
  57.  *    July 1990, e-mail may be sent to uunet!ipel!marking.
  58.  *
  59.  *    Also beginning in July 1990, this code will be archived at the
  60.  *    ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number
  61.  *    for 300/1200/2400 is (602)274-0462. When logging in, specify user
  62.  *    "public", system "bbs", and password "public".
  63.  *
  64.  *    This code is also available from the C Users Group in volume 317.
  65.  *
  66.  * END (from the original source)
  67.  */
  68. #include <stdio.h>
  69. #include <stdlib.h>
  70. #include "tiffcomp.h"
  71.  
  72. #ifndef TRUE
  73. #define    TRUE    1
  74. #define    FALSE    0
  75. #endif
  76.  
  77. #define WHITE    0
  78. #define BLACK    1
  79.  
  80. /*
  81.  * G3 2D and G4 decoding modes.  Note that
  82.  * the vertical modes are ordered so that
  83.  * (mode - MODE_VERT_V0) gives the vertical
  84.  * adjustment for the b1 parameter.
  85.  */
  86. #define MODE_NULL    0
  87. #define MODE_PASS    1
  88. #define MODE_HORIZ    2
  89. #define MODE_VERT_VL3    3
  90. #define MODE_VERT_VL2    4
  91. #define MODE_VERT_VL1    5
  92. #define MODE_VERT_V0    6
  93. #define MODE_VERT_VR1    7
  94. #define MODE_VERT_VR2    8
  95. #define MODE_VERT_VR3    9
  96. #define MODE_UNCOMP    10
  97. #define MODE_ERROR    11
  98. #define MODE_ERROR_1    12
  99.  
  100. unsigned long
  101. append_0(unsigned long prefix)
  102. {
  103.     return (prefix + (1L<<16));
  104. }
  105.  
  106. unsigned long
  107. append_1(unsigned long prefix)
  108. {
  109.     static unsigned short prefix_bit[16] = {
  110.     0x8000, 0x4000, 0x2000, 0x1000,
  111.     0x0800, 0x0400, 0x0200, 0x0100,
  112.     0x0080, 0x0040, 0x0020, 0x0010,
  113.     0x0008, 0x0004, 0x0002, 0x0001
  114.     };
  115.     unsigned char len = (unsigned char)((prefix >> 16) & 0xf);
  116.     return (append_0(prefix) + prefix_bit[len]);
  117. }
  118.  
  119. #define    G3CODES
  120. #include "t4.h"
  121.  
  122. short
  123. search_table(unsigned long prefix, const tableentry* tab, int n)
  124. {
  125.     unsigned short len = (unsigned short)((prefix >> 16) & 0xf);
  126.     unsigned short code = (unsigned short)((prefix & 0xffff) >> (16 - len));
  127.  
  128.     while (n-- > 0) {
  129.     if (tab->length == len && tab->code == code)
  130.         return ((short) tab->runlen);
  131.     tab++;
  132.     }
  133.     return (G3CODE_INCOMP);
  134. }
  135.  
  136. #define    NCODES(a)    (sizeof (a) / sizeof (a[0]))
  137.  
  138. short
  139. white_run_length(unsigned long prefix)
  140. {
  141.     return (search_table(prefix, TIFFFaxWhiteCodes, NCODES(TIFFFaxWhiteCodes)));
  142. }
  143.  
  144. short
  145. black_run_length(unsigned long prefix)
  146. {
  147.     return (search_table(prefix, TIFFFaxBlackCodes, NCODES(TIFFFaxBlackCodes)));
  148. }
  149. #undef NCODES
  150.  
  151. #define MAX_NULLPREFIX    200    /* max # of null-mode prefixes */
  152. typedef    unsigned char NullModeTable[MAX_NULLPREFIX][256];
  153. #define MAX_HORIZPREFIX    250    /* max # of incomplete 1-D prefixes */
  154. typedef    unsigned char HorizModeTable[MAX_HORIZPREFIX][256];
  155.  
  156.   /* the bit string corresponding to this row of the decoding table */
  157. long    null_mode_prefix[MAX_NULLPREFIX];
  158. NullModeTable null_mode;        /* MODE_*, indexed by bit and byte */
  159. NullModeTable null_mode_next_state;    /* next row of decoding tables to use */
  160.   /* number of prefixes or rows in the G4 decoding tables */
  161. short    null_mode_prefix_count = 0;
  162.  
  163. /*
  164.  * 2D uncompressed mode codes.  Note
  165.  * that two groups of codes are arranged
  166.  * so that the decoder can caluclate the
  167.  * length of the run by subtracting the
  168.  * code from a known base value.
  169.  */
  170. #define    UNCOMP_INCOMP    0
  171. /* runs of [0]*1 */
  172. #define    UNCOMP_RUN0    1
  173. #define    UNCOMP_RUN1    2
  174. #define    UNCOMP_RUN2    3
  175. #define    UNCOMP_RUN3    4
  176. #define    UNCOMP_RUN4    5
  177. #define    UNCOMP_RUN5    6
  178. #define    UNCOMP_RUN6    7
  179. /* runs of [0]* w/ terminating color */
  180. #define    UNCOMP_TRUN0    8
  181. #define    UNCOMP_TRUN1    9
  182. #define    UNCOMP_TRUN2    10
  183. #define    UNCOMP_TRUN3    11
  184. #define    UNCOMP_TRUN4    12
  185. /* special code for unexpected EOF */
  186. #define    UNCOMP_EOF    13
  187. /* invalid code encountered */
  188. #define    UNCOMP_INVALID    14
  189.  
  190. long    uncomp_mode_prefix[MAX_NULLPREFIX];
  191. NullModeTable uncomp_mode;
  192. NullModeTable uncomp_mode_next_state;
  193. short    uncomp_mode_prefix_count = 0;
  194.  
  195. /*
  196.  * Decoding action values for horiz_mode.
  197.  */
  198. #define ACT_INCOMP    0        /* incompletely decoded code */
  199. #define ACT_INVALID    1        /* invalide code */
  200. #define ACT_EOL        2        /* end-of-line code */
  201. #define    ACT_RUNT    3        /* terminating run code */
  202. #define    ACT_RUN        66        /* non-terminating run code */
  203. HorizModeTable horiz_mode;
  204.  
  205. /*
  206.  * If the corresponding horiz_mode entry is ACT_INCOMP
  207.  * this entry is a row number for decoding the next byte;
  208.  * otherwise, it is the bit number with which to continue
  209.  * decoding the next codeword.
  210.  */
  211. HorizModeTable horiz_mode_next_state;
  212.         /* prefixes corresponding to the rows of the decoding table */
  213. long    horiz_mode_prefix[MAX_HORIZPREFIX];
  214.         /* color of next run, BLACK or WHITE */
  215. char    horiz_mode_color[MAX_HORIZPREFIX];
  216. short    horiz_mode_prefix_count = 0;
  217.  
  218. static    unsigned char bit_mask[8] =
  219.     { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
  220.  
  221. void    build_null_mode_tables(void);
  222. short    find_horiz_mode_prefix(long, char);
  223. short    find_null_mode_prefix(long);
  224. void    build_horiz_mode_tables(void);
  225. void    build_uncomp_mode_tables(void);
  226. void    write_tables(FILE*);
  227.  
  228. int    verbose = FALSE;
  229. char    *storage_class = "";
  230. int    packoutput = TRUE;
  231. int    oldstyle = FALSE;
  232.  
  233. int
  234. main(int argc, char** argv)
  235. {
  236.     for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
  237.     if (strcmp(argv[0], "-v") == 0) {
  238.         verbose = TRUE;
  239.     } else if (strcmp(argv[0], "-c") == 0) {
  240.         storage_class = "const ";
  241.     } else if (strcmp(argv[0], "-p") == 0) {
  242.         packoutput = FALSE;
  243.     } else if (strcmp(argv[0], "-o") == 0) {
  244.         oldstyle = TRUE;
  245.     } else {
  246.         fprintf(stderr, "Unknown option \"%s\".\n", argv[0]);
  247.         return (-1);
  248.     }
  249.     }
  250.     build_null_mode_tables();        /* null mode decoding tables */
  251.     if (verbose) {
  252.     fprintf(stderr, "%d null mode prefixes defined\n",
  253.         (int) null_mode_prefix_count);
  254.     fprintf(stderr, "building uncompressed mode scripts...\n");
  255.     }
  256.     build_uncomp_mode_tables();        /* uncompressed mode decoding tables */
  257.     if (verbose) {
  258.     fprintf(stderr, "%d uncompressed mode prefixes defined\n",
  259.         (int) uncomp_mode_prefix_count);
  260.     fprintf(stderr, "building 1D scripts...\n");
  261.     }
  262.     build_horiz_mode_tables();        /* 1D decoding tables */
  263.     if (verbose)
  264.     fprintf(stderr, "%d incomplete prefixes defined\n",
  265.         (int) horiz_mode_prefix_count);
  266.     write_tables(stdout);
  267. #ifndef VMS
  268.     return (0);
  269. #else
  270.     exit (0);
  271. #endif
  272. }
  273.  
  274. void
  275. write_null_mode_table(FILE* fd, char* name,
  276.     NullModeTable state, NullModeTable action)
  277. {
  278.     int i, j, lastNonZero;
  279.     char* outersep;
  280.     char* sep;
  281.  
  282.     fprintf(fd, "%su_short\t%s[%d][256] = {", storage_class,
  283.     name, (int) null_mode_prefix_count);
  284.     outersep = "";
  285.     if (!packoutput) {
  286.     for (i = 0; i < null_mode_prefix_count; i++) {
  287.         fprintf(fd, "%s\n/* prefix %d */ {\n", outersep, i);
  288.         sep = "    ";
  289.         for (j = 0; j < 256; j++) {
  290.         fprintf(fd, "%s0x%04x", sep,
  291.             (int) ((action[i][j]<<8)|state[i][j]));
  292.         if (((j+1) % 16) == 0) {
  293.             fprintf(fd, ", /* %3d-%3d */\n", j-15, j);
  294.             sep = "    ";
  295.         } else
  296.             sep = ",";
  297.         }
  298.         fprintf(fd, "}");
  299.         outersep = ",";
  300.     }
  301.     } else {
  302.     for (i = 0; i < null_mode_prefix_count; i++) {
  303.         fprintf(fd, "%s{\n", outersep);
  304.         for (j = 255; j > 0; j--)
  305.         if (state[i][j] != 0 || action[i][j])
  306.             break;
  307.         sep = "";
  308.         lastNonZero = j;
  309.         for (j = 0; j <= lastNonZero; j++) {
  310.         fprintf(fd, "%s%d", sep,
  311.             (int) ((action[i][j]<<8)|state[i][j]));
  312.         if (((j+1) % 24) == 0)
  313.             putc('\n', fd);
  314.         sep = ",";
  315.         }
  316.         fprintf(fd, "}");
  317.         outersep = ",";
  318.     }
  319.     }
  320.     fprintf(fd, "\n};\n");
  321. }
  322.  
  323. void
  324. write_horiz_mode_table(FILE* fd, char* name,
  325.     HorizModeTable state, HorizModeTable action)
  326. {
  327.     int i, j, lastNonZero;
  328.     char* outersep;
  329.     char* sep;
  330.  
  331.     fprintf(fd, "%s u_short\t%s[%d][256] = {", storage_class,
  332.     name, (int) horiz_mode_prefix_count);
  333.     outersep = "";
  334.     if (!packoutput) {
  335.     for (i = 0; i < horiz_mode_prefix_count; i++) {
  336.         fprintf(fd, "%s\n/* prefix %d */ {\n", outersep, i);
  337.         sep = "    ";
  338.         for (j = 0; j < 256; j++) {
  339.         fprintf(fd, "%s0x%04x", sep,
  340.             (int) ((action[i][j]<<8)|state[i][j]));
  341.         if (((j+1) % 14) == 0) {
  342.             fprintf(fd, ", /* %3d-%3d */\n", j-13, j);
  343.             sep = "    ";
  344.         } else
  345.             sep = ",";
  346.         }
  347.         fprintf(fd, "\n}");
  348.         outersep = ",";
  349.     }
  350.     } else {
  351.     outersep = "";
  352.     for (i = 0; i < horiz_mode_prefix_count; i++) {
  353.         fprintf(fd, "%s{\n", outersep);
  354.         for (j = 255; j > 0; j--)
  355.         if (state[i][j] != 0 || action[i][j])
  356.             break;
  357.         sep = "";
  358.         lastNonZero = j;
  359.         for (j = 0; j <= lastNonZero; j++) {
  360.         fprintf(fd, "%s%d", sep,
  361.             (int) ((action[i][j]<<8)|state[i][j]));
  362.         if (((j+1) % 24) == 0)
  363.             putc('\n', fd);
  364.         sep = ",";
  365.         }
  366.         fprintf(fd, "}");
  367.         outersep = ",";
  368.     }
  369.     }
  370.     fprintf(fd, "\n};\n");
  371. }
  372.  
  373. void
  374. write_old_null_mode_table(FILE* fd, char* name, NullModeTable table)
  375. {
  376.     int i, j, lastNonZero;
  377.     char* outersep;
  378.     char* sep;
  379.  
  380.     fprintf(fd, "%su_char\t%s[%d][256] = {", storage_class,
  381.     name, (int) null_mode_prefix_count);
  382.     outersep = "";
  383.     if (!packoutput) {
  384.     for (i = 0; i < null_mode_prefix_count; i++) {
  385.         fprintf(fd, "%s\n/* prefix %d */ {\n", outersep, i);
  386.         sep = "    ";
  387.         for (j = 0; j < 256; j++) {
  388.         fprintf(fd, "%s0x%04x", sep, (int) table[i][j]);
  389.         if (((j+1) % 16) == 0) {
  390.             fprintf(fd, ", /* %3d-%3d */\n", j-15, j);
  391.             sep = "    ";
  392.         } else
  393.             sep = ",";
  394.         }
  395.         fprintf(fd, "}");
  396.         outersep = ",";
  397.     }
  398.     } else {
  399.     for (i = 0; i < null_mode_prefix_count; i++) {
  400.         fprintf(fd, "%s{\n", outersep);
  401.         for (j = 255; j > 0; j--)
  402.         if (table[i][j] != 0)
  403.             break;
  404.         sep = "";
  405.         lastNonZero = j;
  406.         for (j = 0; j <= lastNonZero; j++) {
  407.         fprintf(fd, "%s%d", sep, (int) table[i][j]);
  408.         if (((j+1) % 24) == 0)
  409.             putc('\n', fd);
  410.         sep = ",";
  411.         }
  412.         fprintf(fd, "}");
  413.         outersep = ",";
  414.     }
  415.     }
  416.     fprintf(fd, "\n};\n");
  417. }
  418.  
  419. void
  420. write_old_horiz_mode_table(FILE* fd, char* name, HorizModeTable table)
  421. {
  422.     int i, j, lastNonZero;
  423.     char* outersep;
  424.     char* sep;
  425.  
  426.     fprintf(fd, "%s u_char\t%s[%d][256] = {", storage_class,
  427.     name, (int) horiz_mode_prefix_count);
  428.     outersep = "";
  429.     if (!packoutput) {
  430.     for (i = 0; i < horiz_mode_prefix_count; i++) {
  431.         fprintf(fd, "%s\n/* prefix %d */ {\n", outersep, i);
  432.         sep = "    ";
  433.         for (j = 0; j < 256; j++) {
  434.         fprintf(fd, "%s0x%04x", sep, (int) table[i][j]);
  435.         if (((j+1) % 14) == 0) {
  436.             fprintf(fd, ", /* %3d-%3d */\n", j-13, j);
  437.             sep = "    ";
  438.         } else
  439.             sep = ",";
  440.         }
  441.         fprintf(fd, "\n}");
  442.         outersep = ",";
  443.     }
  444.     } else {
  445.     outersep = "";
  446.     for (i = 0; i < horiz_mode_prefix_count; i++) {
  447.         fprintf(fd, "%s{\n", outersep);
  448.         for (j = 255; j > 0; j--)
  449.         if (table[i][j] != 0)
  450.             break;
  451.         sep = "";
  452.         lastNonZero = j;
  453.         for (j = 0; j <= lastNonZero; j++) {
  454.         fprintf(fd, "%s%d", sep, (int) table[i][j]);
  455.         if (((j+1) % 24) == 0)
  456.             putc('\n', fd);
  457.         sep = ",";
  458.         }
  459.         fprintf(fd, "}");
  460.         outersep = ",";
  461.     }
  462.     }
  463.     fprintf(fd, "\n};\n");
  464. }
  465.  
  466. void
  467. write_define(FILE* fd, char* name, int value, char* comment)
  468. {
  469.     fprintf(fd, "#define\t%s\t%d", name, value);
  470.     if (!packoutput && comment)
  471.     fprintf(fd, "\t/* %s */", comment);
  472.     fprintf(fd, "\n");
  473. }
  474.  
  475. void
  476. write_preamble(FILE* fd)
  477. {
  478.     fprintf(fd, "%s\n",
  479. "/* DO NOT EDIT THIS FILE, IT WAS AUTOMATICALLY CREATED BY mkg3state */");
  480.     write_define(fd, "ACT_INCOMP", ACT_INCOMP, "incompletely decoded code");
  481.     write_define(fd, "ACT_INVALID", ACT_INVALID, "invalide code");
  482.     write_define(fd, "ACT_EOL", ACT_EOL, "end-of-line code");
  483.     write_define(fd, "ACT_RUNT", ACT_RUNT, "terminating run code");
  484.     write_define(fd, "ACT_RUN", ACT_RUN, "non-terminating run code");
  485.     fprintf(fd, "\n");
  486.     fprintf(fd, "/* modes that the decoder can be in */\n");
  487.     write_define(fd, "MODE_NULL", MODE_NULL, NULL);
  488.     write_define(fd, "MODE_PASS", MODE_PASS, NULL);
  489.     write_define(fd, "MODE_HORIZ", MODE_HORIZ, NULL);
  490.     write_define(fd, "MODE_VERT_V0", MODE_VERT_V0, NULL);
  491.     write_define(fd, "MODE_VERT_VR1", MODE_VERT_VR1, NULL);
  492.     write_define(fd, "MODE_VERT_VR2", MODE_VERT_VR2, NULL);
  493.     write_define(fd, "MODE_VERT_VR3", MODE_VERT_VR3, NULL);
  494.     write_define(fd, "MODE_VERT_VL1", MODE_VERT_VL1, NULL);
  495.     write_define(fd, "MODE_VERT_VL2", MODE_VERT_VL2, NULL);
  496.     write_define(fd, "MODE_VERT_VL3", MODE_VERT_VL3, NULL);
  497.     write_define(fd, "MODE_UNCOMP", MODE_UNCOMP, NULL);
  498.     write_define(fd, "MODE_ERROR", MODE_ERROR, NULL);
  499.     write_define(fd, "MODE_ERROR_1", MODE_ERROR_1, NULL);
  500.     fprintf(fd, "\n");
  501.     write_define(fd, "UNCOMP_INCOMP", UNCOMP_INCOMP, NULL);
  502.     fprintf(fd, "/* runs of [0]*1 */\n");
  503.     write_define(fd, "UNCOMP_RUN0", UNCOMP_RUN0, NULL);
  504.     write_define(fd, "UNCOMP_RUN1", UNCOMP_RUN1, NULL);
  505.     write_define(fd, "UNCOMP_RUN2", UNCOMP_RUN2, NULL);
  506.     write_define(fd, "UNCOMP_RUN3", UNCOMP_RUN3, NULL);
  507.     write_define(fd, "UNCOMP_RUN4", UNCOMP_RUN4, NULL);
  508.     write_define(fd, "UNCOMP_RUN5", UNCOMP_RUN5, NULL);
  509.     write_define(fd, "UNCOMP_RUN6", UNCOMP_RUN6, NULL);
  510.     fprintf(fd, "/* runs of [0]* w/ terminating color */\n");
  511.     write_define(fd, "UNCOMP_TRUN0", UNCOMP_TRUN0, NULL);
  512.     write_define(fd, "UNCOMP_TRUN1", UNCOMP_TRUN1, NULL);
  513.     write_define(fd, "UNCOMP_TRUN2", UNCOMP_TRUN2, NULL);
  514.     write_define(fd, "UNCOMP_TRUN3", UNCOMP_TRUN3, NULL);
  515.     write_define(fd, "UNCOMP_TRUN4", UNCOMP_TRUN4, NULL);
  516.     fprintf(fd, "/* special code for unexpected EOF */\n");
  517.     write_define(fd, "UNCOMP_EOF", UNCOMP_EOF, NULL);
  518.     fprintf(fd, "/* invalid code encountered */\n");
  519.     write_define(fd, "UNCOMP_INVALID", UNCOMP_INVALID, NULL);
  520.     fprintf(fd, "/* codes >= terminate uncompress mode */\n");
  521.     fprintf(fd, "#define\tUNCOMP_EXIT    UNCOMP_TRUN0\n");
  522.     fprintf(fd, "\n");
  523. }
  524.  
  525. void
  526. extern_table(FILE* fd, char* type, char* name)
  527. {
  528.     fprintf(fd, "extern\t%s%s %s[][256];\n", storage_class, type, name);
  529. }
  530.  
  531. void
  532. write_tables(FILE* fd)
  533. {
  534.     write_preamble(fd);
  535.     fprintf(fd, "#ifdef G3STATES\n");
  536.     if (oldstyle) {
  537.     write_old_null_mode_table(fd, "TIFFFax2DFSM", null_mode_next_state);
  538.     write_old_null_mode_table(fd, "TIFFFax2DFSMAction", null_mode);
  539.     write_old_null_mode_table(fd, "TIFFFaxUncompFSM",
  540.         uncomp_mode_next_state);
  541.     write_old_null_mode_table(fd, "TIFFFaxUncompFSMAction", uncomp_mode);
  542.     write_old_horiz_mode_table(fd, "TIFFFax1DFSM", horiz_mode_next_state);
  543.     write_old_horiz_mode_table(fd, "TIFFFax1DFSMAction", horiz_mode);
  544.     fprintf(fd, "#else\n");
  545.     extern_table(fd, "u_char", "TIFFFax2DFSM");
  546.     extern_table(fd, "u_char", "TIFFFax2DFSMAction");
  547.     extern_table(fd, "u_char", "TIFFFaxUncompFSM");
  548.     extern_table(fd, "u_char", "TIFFFaxUncompFSMAction");
  549.     extern_table(fd, "u_char", "TIFFFax1DFSM");
  550.     extern_table(fd, "u_char", "TIFFFax1DFSMAction");
  551.     } else {
  552.     write_null_mode_table(fd, "TIFFFax2DFSM",
  553.         null_mode_next_state, null_mode);
  554.     write_null_mode_table(fd, "TIFFFaxUncompFSM",
  555.         uncomp_mode_next_state, uncomp_mode);
  556.     write_horiz_mode_table(fd, "TIFFFax1DFSM",
  557.         horiz_mode_next_state, horiz_mode);
  558.     fprintf(fd, "#else\n");
  559.     extern_table(fd, "u_short", "TIFFFax2DFSM");
  560.     extern_table(fd, "u_short", "TIFFFaxUncompFSM");
  561.     extern_table(fd, "u_short", "TIFFFax1DFSM");
  562.     }
  563.     fprintf(fd, "#endif\n");
  564. }
  565.  
  566. short
  567. find_null_mode_prefix(long prefix)
  568. {
  569.     short j1;
  570.  
  571.     if (prefix == 0L)
  572.     return (0);
  573.     for (j1 = 8; j1 < null_mode_prefix_count; j1++)
  574.     if (prefix == null_mode_prefix[j1])
  575.         return (j1);
  576.     if (null_mode_prefix_count == MAX_NULLPREFIX) {
  577.     fprintf(stderr, "ERROR: null mode prefix table overflow\n");
  578.     exit(1);
  579.     }
  580.     if (verbose)
  581.     fprintf(stderr, "adding null mode prefix[%d] 0x%lx\n",
  582.         (int) null_mode_prefix_count, prefix);
  583.     null_mode_prefix[null_mode_prefix_count++] = prefix;
  584.     return (null_mode_prefix_count-1);
  585. }
  586.  
  587. short
  588. find_horiz_mode_prefix(long prefix, char color)
  589. {
  590.     short j1;
  591.  
  592.     for (j1 = 0; j1 < horiz_mode_prefix_count; j1++)
  593.     if (prefix == horiz_mode_prefix[j1] && horiz_mode_color[j1] == color)
  594.         return (j1);
  595.     /*
  596.      * It wasn't found, so add it to the tables, but first, is there room?
  597.      */
  598.     if (horiz_mode_prefix_count == MAX_HORIZPREFIX) {
  599.     fprintf(stderr, "ERROR: 1D prefix table overflow\n");
  600.     exit(1);
  601.     }
  602.     /* OK, there's room... */
  603.     if (verbose)
  604.     fprintf(stderr, "adding horiz mode prefix[%d] 0x%lx (color %c)\n",
  605.         (int) horiz_mode_prefix_count, prefix, "WB"[color]);
  606.     horiz_mode_prefix[horiz_mode_prefix_count] = prefix;
  607.     horiz_mode_color[horiz_mode_prefix_count] = color;
  608.     horiz_mode_prefix_count++;
  609.     return (horiz_mode_prefix_count - 1);
  610. }
  611.  
  612. short
  613. find_uncomp_mode_prefix(long prefix)
  614. {
  615.     short j1;
  616.  
  617.     if (prefix == 0L)
  618.     return (0);
  619.     for (j1 = 8; j1 < uncomp_mode_prefix_count; j1++)
  620.     if (prefix == uncomp_mode_prefix[j1])
  621.         return (j1);
  622.     if (uncomp_mode_prefix_count == MAX_NULLPREFIX) {
  623.     fprintf(stderr, "ERROR: uncomp mode prefix table overflow\n");
  624.     exit(1);
  625.     }
  626.     if (verbose)
  627.     fprintf(stderr, "adding uncomp mode prefix[%d] 0x%lx\n",
  628.         (int) uncomp_mode_prefix_count, prefix);
  629.     uncomp_mode_prefix[uncomp_mode_prefix_count++] = prefix;
  630.     return (uncomp_mode_prefix_count-1);
  631. }
  632.  
  633. short
  634. null_mode_type(unsigned long prefix)
  635. {
  636.     switch (prefix) {
  637.     case 0x18000L: return (MODE_VERT_V0);    /* 1 */
  638.     case 0x36000L: return (MODE_VERT_VR1);    /* 011 */
  639.     case 0x34000L: return (MODE_VERT_VL1);    /* 010 */
  640.     case 0x32000L: return (MODE_HORIZ);        /* 001 */
  641.     case 0x41000L: return (MODE_PASS);        /* 0001 */
  642.     case 0x60C00L: return (MODE_VERT_VR2);    /* 0000 11 */
  643.     case 0x60800L: return (MODE_VERT_VL2);    /* 0000 10 */
  644.     case 0x70600L: return (MODE_VERT_VR3);    /* 0000 011 */
  645.     case 0x70400L: return (MODE_VERT_VL3);    /* 0000 010 */
  646.     case 0x80200L: return (MODE_ERROR);        /* 0000 0010 */
  647.     case 0x90300L: return (MODE_ERROR);        /* 0000 0011 0 */
  648.     case 0xA0380L: return (MODE_ERROR);        /* 0000 0011 10 */
  649.     case 0xA03C0L: return (MODE_UNCOMP);    /* 0000 0011 11 */
  650.     /*
  651.      * Under the assumption that there are no
  652.      * errors in the file, then this bit string
  653.      * can only be the beginning of an EOL code.
  654.      */
  655.     case 0x70000L: return (MODE_ERROR_1);    /* 0000 000 */
  656.  
  657.     default:       return (MODE_NULL);        /* incomplete */
  658.     }
  659. }
  660.  
  661. short
  662. uncomp_mode_type(unsigned long prefix)
  663. {
  664.     short code;
  665.     short len;
  666.     switch (prefix) {
  667.     case 0x18000L: return (UNCOMP_RUN1);    /* 1 */
  668.     case 0x24000L: return (UNCOMP_RUN2);    /* 01 */
  669.     case 0x32000L: return (UNCOMP_RUN3);    /* 001 */
  670.     case 0x41000L: return (UNCOMP_RUN4);    /* 0001 */
  671.     case 0x50800L: return (UNCOMP_RUN5);    /* 0000 1 */
  672.     case 0x60400L: return (UNCOMP_RUN6);    /* 0000 01 */
  673.     case 0x70200L: return (UNCOMP_TRUN0);    /* 0000 001 */
  674.     case 0x80100L: return (UNCOMP_TRUN1);    /* 0000 0001 */
  675.     case 0x90080L: return (UNCOMP_TRUN2);    /* 0000 0000 1 */
  676.     case 0xA0040L: return (UNCOMP_TRUN3);    /* 0000 0000 01 */
  677.     case 0xB0020L: return (UNCOMP_TRUN4);    /* 0000 0000 001 */
  678.     }
  679.     code = (short)(prefix & 0xffffL);
  680.     len = (short)((prefix >> 16) & 0xf);
  681.     return ((code || len > 10) ? UNCOMP_INVALID : -1);
  682. }
  683.  
  684. #define    BASESTATE(b)    ((unsigned char) ((b) & 0x7))
  685.  
  686. void
  687. build_null_mode_tables(void)
  688. {
  689.     short prefix;
  690.  
  691.     /*
  692.      * Note: the first eight entries correspond to a null
  693.      * bitstring prefix and starting bit numbers 0-7.
  694.      */
  695.     null_mode_prefix_count = 8;
  696.     for (prefix = 0; prefix < null_mode_prefix_count; prefix++) {
  697.     short byte;
  698.     for (byte = 0; byte < 256; byte++) {
  699.         short firstbit;
  700.         short bit;
  701.         short mode;
  702.         unsigned long curprefix;
  703.  
  704.         if (prefix < 8) {
  705.         curprefix = 0L;
  706.         firstbit = prefix;
  707.         } else {
  708.         curprefix = null_mode_prefix[prefix];
  709.         firstbit = 0;
  710.         }
  711.         /*
  712.          * Search for the next bit in this byte
  713.          * for which a code word is recognized.
  714.          */
  715.         mode = MODE_NULL;
  716.         for (bit = firstbit; bit < 8; bit++) {
  717.         curprefix = (byte & bit_mask[bit]) ?
  718.             append_1(curprefix) : append_0(curprefix);
  719.         mode = null_mode_type(curprefix);
  720.         if (mode != MODE_NULL)
  721.             break;
  722.         }
  723.         if (mode != MODE_NULL) {
  724.         /*
  725.          * A code word was recognized.  Record the bit number
  726.          * with which to restart decoding--the decoder knows
  727.          * to interpret the ``state'' accordingly.
  728.          *
  729.          * NB: if the bit number is 8, then the table
  730.          * entry will be zero, which indicates a new byte
  731.          * is to be fetched during the decoding process
  732.          */
  733.         null_mode_next_state[prefix][byte] = BASESTATE(bit+1);
  734.         } else {
  735.         /*
  736.          * No code word was recognized yet.  If this is a new
  737.          * bitstring prefix then this call will cause a new
  738.          * row (state) to be allocated in the table.
  739.          */
  740.         null_mode_next_state[prefix][byte] = (unsigned char)
  741.             find_null_mode_prefix(curprefix);
  742.         }
  743.         null_mode[prefix][byte] = (unsigned char) mode;
  744.     }
  745.     }
  746. }
  747.  
  748. void
  749. build_horiz_mode_tables(void)
  750. {
  751.     unsigned short byte;
  752.     short prefix;
  753.  
  754.     /*
  755.      * The first 8 are for white,
  756.      * the second 8 are for black,
  757.      * beginning with bits 0-7.
  758.      */
  759.     horiz_mode_prefix_count = 16;
  760.     for (prefix = 0; prefix < horiz_mode_prefix_count; prefix++)
  761.     for (byte = 0; byte < 256; byte++) {
  762.         short bit;
  763.         short firstbit;
  764.         short runlength;
  765.         char color;
  766.         unsigned long curprefix;
  767.  
  768.         if (prefix < 8) {
  769.         color = WHITE;
  770.         curprefix = 0L;
  771.         firstbit = prefix;
  772.         } else if (prefix < 16) {
  773.         color = BLACK;
  774.         curprefix = 0L;
  775.         firstbit = prefix - 8;
  776.         } else {
  777.         color = horiz_mode_color[prefix];
  778.         curprefix = horiz_mode_prefix[prefix];
  779.         firstbit = 0;
  780.         }
  781.         /*
  782.          * Search for the next bit in this byte
  783.          * for which a code word is recognized.
  784.          */
  785.         for (bit = firstbit; bit < 8; bit++) {
  786.         curprefix = (byte & bit_mask[bit]) ?
  787.             append_1(curprefix) : append_0(curprefix);
  788.         /*
  789.          * The following conversion allows for arbitrary strings of
  790.          * zeroes to precede the end-of-line code 0000 0000 0001.
  791.          * It assumes no errors in the data, and is based on
  792.          * the assumption that the code replaced (12 consecutive
  793.          * zeroes) can only be "legally" encountered before the
  794.          * end-of-line code.  This assumption is valid only for
  795.          * a Group 3 image; the combination will never occur
  796.          * in horizontal mode in a proper Group 4 image.
  797.          */
  798.         if (curprefix == 0xC0000L)
  799.             curprefix = 0xB0000L;
  800.         runlength = (color == WHITE) ? 
  801.             white_run_length(curprefix) : black_run_length(curprefix);
  802.         if (runlength != G3CODE_INCOMP)
  803.             break;
  804.         }
  805.         switch (runlength) {
  806.         case G3CODE_INVALID:        /* invalid codeword */
  807.         horiz_mode[prefix][byte] = (unsigned char) ACT_INVALID;
  808.         /* NB: restart decoding with this bit */
  809.         horiz_mode_next_state[prefix][byte] = (unsigned char) bit;
  810.         break;
  811.         case G3CODE_EOL:            /* Group 3 EOL codeword */
  812.         horiz_mode[prefix][byte] = (unsigned char) ACT_EOL;
  813.         horiz_mode_next_state[prefix][byte] = BASESTATE(bit+1);
  814.         break;
  815.         default:                /* runlength codeword */
  816.         horiz_mode[prefix][byte] = (unsigned char)
  817.             (runlength < 64 ?
  818.             ACT_RUNT + runlength :
  819.             ACT_RUNT + 64 + (runlength / 64));
  820.         horiz_mode_next_state[prefix][byte] = BASESTATE(bit+1);
  821.         break;
  822.         case G3CODE_INCOMP:            /* incomplete codeword */
  823.         horiz_mode[prefix][byte] = (unsigned char) ACT_INCOMP;
  824.         horiz_mode_next_state[prefix][byte] = (unsigned char)
  825.             find_horiz_mode_prefix(curprefix, color) +
  826.             (color == WHITE ? 0 : -8);
  827.         break;
  828.         }
  829.     }
  830. }
  831.  
  832. void
  833. build_uncomp_mode_tables(void)
  834. {
  835.     short prefix;
  836.  
  837.     /*
  838.      * Note: the first eight entries correspond to
  839.      * a null prefix and starting bit numbers 0-7.
  840.      */
  841.     uncomp_mode_prefix_count = 8;
  842.     for (prefix = 0; prefix < uncomp_mode_prefix_count; prefix++) {
  843.     short byte;
  844.     for (byte = 0; byte < 256; byte++) {
  845.         short firstbit;
  846.         short bit;
  847.         unsigned long curprefix;
  848.         char found_code = FALSE;
  849.  
  850.         if (prefix < 8) {
  851.         curprefix = 0L;
  852.         firstbit = prefix;
  853.         } else {
  854.         curprefix = uncomp_mode_prefix[prefix];
  855.         firstbit = 0;
  856.         }
  857.         for (bit = firstbit; bit < 8 && !found_code; bit++) {
  858.         short mode;
  859.  
  860.         if (bit_mask[bit] & byte)
  861.             curprefix = append_1(curprefix);
  862.         else
  863.             curprefix = append_0(curprefix);
  864.         mode = uncomp_mode_type(curprefix);
  865.         if (mode != -1) {
  866.             /*
  867.              * NOTE: if the bit number is 8, then the table
  868.              * entry will be zero, which indicates a new byte
  869.              * is to be fetched during the decoding process
  870.              */
  871.             found_code = TRUE;
  872.             uncomp_mode[prefix][byte] = (unsigned char) mode;
  873.             uncomp_mode_next_state[prefix][byte] = BASESTATE(bit+1);
  874.             break;
  875.         }
  876.         }
  877.         if (!found_code) {
  878.         uncomp_mode_next_state[prefix][byte] = (unsigned char)
  879.             find_uncomp_mode_prefix(curprefix);
  880.         /*
  881.          * This indicates to the decoder that
  882.          * no valid code has yet been identified.
  883.          */
  884.         uncomp_mode[prefix][byte] = UNCOMP_INCOMP;
  885.         }
  886.     }
  887.     }
  888. }
  889.